use std::{net::TcpListener, thread, io::{Read, Write}};

use crate::{connection, router, request, message};

pub struct Engine {
    addr:String,
    max_packet_size:u32,
    pre_hook:fn(&mut connection::Conn),
    post_hook:fn(&mut connection::Conn),
}

impl Engine {
    pub fn new(addr:String, max_packet_size:u32, pre_hook:fn(&mut connection::Conn), post_hook:fn(&mut connection::Conn)) -> Self {
        Engine{
            addr,
            max_packet_size,
            pre_hook,
            post_hook,
        }
    }

    pub fn run(&self) {
        println!("listenner at addr {}, server running...", self.addr);
        let lis = TcpListener::bind(self.addr.as_str()).unwrap();
        let pre_hook = self.pre_hook;
        let post_hook = self.post_hook;
        //阻塞等待客户端连接，处理客户端连接业务(读,写)
        for conn in lis.incoming() {
            let conn = conn.unwrap();
            println!("connection establishment, remote addr {}", conn.peer_addr().unwrap().to_string());
            //封装tcp conn得到connection模块
            let mut conn = connection::Conn::new(conn);
            // 异步处理业务
            thread::spawn(move ||{
                pre_hook(&mut conn);
                conn.start();
                post_hook(&mut conn);
            });
        }
    }
    
    pub fn regist(&self, id: u32, func: fn(&mut connection::Conn, message::Message)) {
        router::regist(id, func);
    }
}